package cn.tedu.sp06.filter;

import cn.tedu.web.util.JsonResult;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/* Zuul 会自动配置过滤器*/
@Component
public class AccessFilter extends ZuulFilter {
    @Override
    /*设置过滤器的类型： pre前置, routing, post后置, error错误*/
    public String filterType() {
        // return "pre";这种和下面那种写法也都可以
        /*获取过滤器常量 FilterConstants.PRE_TYPE="pre"*/
        return FilterConstants.PRE_TYPE;
    }

    @Override
    /*设置自定义过滤器放在类型过滤器的哪个执行顺序
    * 默认已经有五个前置过滤器,规定必须将自定义过滤器放在第六位*/
    public int filterOrder() {
        return 6;
    }

    @Override
    /*判断当前请求，是否需要执行下面的过滤代码
    public Object run() throws ZuulException{}*/
    public boolean shouldFilter() {
        /**业务:
         * 调用商品服务，执行权限判断；
         * 调用用户服务或者订单服务，不执行权限判断*/

        /*获得当前请求的上下文对象*/
        RequestContext ctx = RequestContext.getCurrentContext();
        /*ctx里面保存以KV形式存储的上下文对象,如果你要调用哪个服务,serviceId
        就作为Key,找到对应的Value,Value就是你要调用的服务注册在Eureka注册中心注册的id,
        因此可以通过serviceId获得对应的服务id*/
        /*"serviceId"=ctx.get(FilterConstants.SERVICE_ID_KEY*/
        //String serviceId = (String)ctx.get("serviceId");也可以这么写
        String serviceId = (String)
                ctx.get(FilterConstants.SERVICE_ID_KEY);//("serviceId");
        /*使用.equalsIgnoreCase()方法 --IgnoreCase忽略大小写方法
        * 判断 service id 是否是 "item-service"(商品服务),用来判断是否
        * 调用了商品服务,如果是则返回true,则执行过滤代码方法
        * public Object run() throws ZuulException判断他有没有登录*/
        return "item-service".equalsIgnoreCase(serviceId);
    }

    @Override
    /*执行过滤代码,判断他有没有登录*/
    public Object run() throws ZuulException {
        //http://localhost:3001/item-service/i6juh65g4f3?jwt=iu5hyg45f34t43y
        /*获得当前请求的上下文对象*/
        RequestContext ctx = RequestContext.getCurrentContext();
        /*从上下文得到 request 对象,获取该对象封装的所有请求协议*/
        HttpServletRequest request = ctx.getRequest();
        /*用 request 获取 jwt 参数,查看是否有令牌*/
        String jwt = request.getParameter("jwt");
        /*使用apache的StringUtils.isBlank(jwt)API判断令牌是否存在
        如果令牌不存在或是空串或者是空字符，阻止继续调用，直接返回响应*/
        if (StringUtils.isBlank(jwt)) {
            /* 阻止继续调用服务*/
            ctx.setSendZuulResponse(false);
            /* 直接返回未登录响应,403状态码,没有登录信息,什么资料也没有
            * 因此返回的结果格式应该为Json形式的JsonResult - {code:403,msg:"没有登录",data:null}
            *使用JsonResult toString方法(实际上是JsonUtil(this))将字符串转换成json串 */
            String json =
                JsonResult.build().code(403).msg("没有登录").toString();
            /*发送响应要使用协议头协议体,
            协议头告诉客户端我是用的是什么格式,你要用什么编码打开*/
            ctx.addZuulResponseHeader("Content-Type", "application/json;charset=UTF-8");
            /*协议体是响应到客户端的数据*/
            ctx.setResponseBody(json);
        }
        /*zuul目前版本返回值还没有任何作用*/
        return null;
    }
}
